package rsi.mesoscopic.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class Node {

	private String mId;
	
	private int mY;
	
	private int mX;
	
	private List<Node> mOutcomingNodes;
	
	private List<Node> mIncomingNodes;
	
	private List<NodeData> mCachedData;
	
	private List<String> mIncomingNodesGreen;
	
	private int mCurrentStep = 0;
		
	public Node(String id) {
		mId = id;
		
		mOutcomingNodes = new ArrayList<Node>();
		mIncomingNodes = new ArrayList<Node>();
		mCachedData = new ArrayList<Node.NodeData>();
		mIncomingNodesGreen = new ArrayList<String>();
	}
	
	public void addOutcomingNode(Node n) {
		mOutcomingNodes.add(n);
	}
	
	public Node getOutcomingNode(int i) {
		return mOutcomingNodes.get(i);
	}
	
	public Collection<Node> getOutcomingNodes() {
		return mOutcomingNodes;
	}
	
	public void addIncomingNode(Node n) {
		mIncomingNodes.add(n);
	}
	
	public Node getIncomingNode(int i) {
		return mIncomingNodes.get(i);
	}
	
	public Collection<Node> getIncomingNodes() {
		return mIncomingNodes;
	}
	
	public boolean addPhase(String str) {
		mIncomingNodesGreen.add(str);
		
		return true;
	}

	public int getY() {
		return mY;
	}

	public void setY(int y) {
		mY = y;
	}

	public int getX() {
		return mX;
	}

	public void setX(int x) {
		mX = x;
	}

	public String getId() {
		return mId;
	}
	
	public int indexOfIncomingNode(String id) {
		for(int i = 0; i < mIncomingNodes.size(); i++) {
			if(mIncomingNodes.get(i).getId().equals(id)) {
				return i;
			}
		}
		
		return -1;
	}
	
	public int getQueue(int incomingIndex) {
		NodeData data = mCachedData.get(mCurrentStep);
		
		return data.mQueue[incomingIndex];
	}
	
	public char getTrafficLightStatus(String direction) {
	
		if(mCurrentStep == -1 || mIncomingNodesGreen.size() == 0 || mIncomingNodesGreen.size() == 1) {
			return '-';
		}
		
		NodeData data = mCachedData.get(mCurrentStep);
		
		if(mIncomingNodesGreen.get(data.mPhase).equals(direction)) {
			return 'g';
		}
		
		return 'r';
	}
	
	public void setStep(int step) {		
		mCurrentStep = step;
	}
	
	public void nextStep() {
		setStep(mCurrentStep+1);
	}
	
	public void previousStep() {
		setStep(mCurrentStep-1);
	}
	
	public int getStepCount() {
		return mCachedData.size();
	}
	
	public void appendData(int[] queue, int[] flush, int phaseId, int time, int step) {
		NodeData nd = new NodeData();
		nd.mFlush = flush;
		nd.mQueue = queue;
		nd.mPhase = phaseId;
		nd.mTime = time;
		
		mCachedData.add(nd);
	}
	
	private static class NodeData implements Serializable {

		private static final long serialVersionUID = 5489704822745145473L;

		public int[] mFlush;
		
		public int[] mQueue;
		
		public int mPhase = -1;
		
		public int mTime = -1;
	}
}
